﻿<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>Rico LiveGrid AJAX</title>
<link href="ricoDocs.css" rel="Stylesheet" type="text/css">

<style type="text/css">
.request, .response {
  border: 1px solid black;
  background-color: #FFF8DC;
  padding: 4px;
}
dt span {
  font-weight:normal;
  font-style:italic;
}
</style>
</head>

<body>
<h1>Rico LiveGrid AJAX</h1>

<p>Rico LiveGrid の鍵となる特徴の一つは AJAX を通して動的にデータをロードするその能力です。
このドキュメントは、LiveGrid AJAX のリクエストとレスポンスのフォーマットに焦点を合わせます。
より明確には、LiveGrid <strong>バッファ</strong>オブジェクトがリクエストを生成し、レスポンスを処理します。
それで、もし支配外のウェブサービスからデータが来る状況下にいるなら、ウェブサービスと LiveGrid 
の間のインタフェースとして用いられるカスタム LiveGrid バッファクラスを作成して下さい。
しかし、このドキュメントでは Rico ディストリビューションに付属するバッファクラスのリクエストと
レスポンスのフォーマットに焦点を合わせます。

<p>Rico ディストリビューションは 4 つの異なるバッファクラスを含みます。
<dl>
<dt>Rico.Buffer.Base
<dd>AJAX では無い（すなわち XMLHttpRequest の呼び出しの無い）静的なデータセットの利用。
データは HTML テーブル又は javascript 配列からロードされる事が出来ます。
このバッファは AJAX を利用しないので、このドキュメントでこれ以上議論されません。
<dt><a href='#AjaxXML'>Rico.Buffer.AjaxXML</a>
<dd>すべての LiveGrid データは一回の AJAX の呼び出しでロードされ、データは XML フォーマットで返されます
<dt><a href='#AjaxSQL'>Rico.Buffer.AjaxSQL</a>
<dd>LiveGrid のデータは、ユーザがグリッドを通してスクロールすることにより、塊でロードされます
<dt><a href='#AjaxJSON'>Rico.Buffer.AjaxJSON</a>
<dd>レスポンスが JSON フォーマットである事を除いては AjaxSQL と同じです
</dl>

<h2><a name='AjaxXML'>Rico.Buffer.AjaxXML</a></h2>

<p>AjaxXML バッファは、LiveGrid でユーザが行うスクロールの量を考慮しないで、
一回の XMLHttpRequest の実行だけを行います。
AjaxXML バッファは以下の javascript を利用して生成されます。

<pre>
buffer=new Rico.Buffer.AjaxXML(url,options,ajaxOptions)
</pre>

<dl>
<dt>url
<dd>データプロバイダへの url を含んでいる文字列。
<dt>options
<dd>以下のどれかを含む Rico バッファオプションオブジェクト。

<dl>
<dt>bufferTimeout
<dd>タイムアウトを示す前に待ちメッセージをユーザに表示すべきミリ秒の数を指定する整数
デフォルトは 20000 （20 秒）。

<dt>requestParameters
<dd>XMLHttpRequest の検索文字列に加えられる "parm=value" の形の文字列の配列。

<dt>isEncoded
<dd>レスポンスが HTML エンコードされるかどうかを指定します。デフォルトは true です。
Rico と共に提供されるすべてのプラグインは、レスポンスをエンコードします。

<dt>waitMsg
<dd>XMLHttpRequest レスポンスを待つ間ユーザに表示されるメッセージ。
デフォルトは RicoTranslate.getPhraseById("waitForData")。
これがイメージタグである事が出来る点に注意して下さい、例えば。
<pre>
buffer=new Rico.Buffer.AjaxXML(
  url,
  {waitMsg: "&lt;img src='MySpinner.gif'&gt;"},
  ajaxOptions);
</pre>

<dt>canFilter
<dd>バッファがフィルタリングをサポートするかどうかを示す真偽値。デフォルトは true です。
</dl>

<dt>ajaxOptions
<dd>Prototype の Ajax.Request メソッドに渡す 
<a href='http://prototypejs.org/api/ajax/options'>Ajax オプションオブジェクト</a>。
"parameters" と "onComplete" オプションが指定されるならば、Rico によって利用され、
エフェクトを持ちません。
"method" オプションはデフォルトで "get" ですが、オーバーライドされる事が出来ます。
</dl>

ここに ex3livegridxml.php から取った実例があります。
<pre>
buffer=new Rico.Buffer.AjaxXML('ricoXMLquery.php');
ex3=new Rico.LiveGrid ('ex3', buffer, grid_options);
</pre>

<h3>AjaxXML リクエスト</h3>

<p>grid_options.prefetchBuffer が true （それはデフォルトです）なら、グリッドの初期化の間に、
ricoXMLquery.php からデータをフェッチする、一つの XMLHttpRequest が生成されます。
この URL は、以下のクエリーストリング（検索）パラメータを含みます。

<dl>
<dt>id
<dd>以前の実例 "ex3" の Rico.LiveGrid() の呼び出しで、
最初のパラメータとして指定されたグリッドの id。
<dt>offset
<dd>返さなければならないデータセットの最初のレコード。 AjaxXML では常に "0" です。
<dt>page_size
<dd>データセットで返されなければならないレコードの数。
AjaxXML では常に "-1" で、すべてのレコードが返されなければならない事を意味します。
</dl>

<p>加えて、options.requestParameters が指定されるならば、それらもまた含まれる事になります。
そして、ex3 のためのデータのフェッチに利用される完全な URL は、次の通りです。
<pre class='request'>
ricoXMLquery.php?id=ex3&amp;offset=0&amp;page_size=-1
</pre>

<h3><a name='AjaxXMLresponse'>AjaxXML レスポンス</a></h3>

<p>ここに ex3 の LiveGrid を実装するサンプルのレスポンスがあります。

<pre class='response'>
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;ajax-response&gt;
  &lt;response type='object' id='ex3_updater'&gt;
    &lt;rows update_ui='true' offset='0'&gt;
    &lt;tr&gt;&lt;td&gt;Data for row 1, cell 1&lt;/td&gt;&lt;td&gt;Data for row 1, cell 2&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;Data for row 2, cell 1&lt;/td&gt;&lt;td&gt;Data for row 2, cell 2&lt;/td&gt;&lt;/tr&gt;
    &lt;/rows&gt;
    &lt;rowcount&gt;2&lt;/rowcount&gt;
    &lt;debug&gt;Generated by test server&lt;/debug&gt;
  &lt;/response&gt;
&lt;/ajax-response&gt;
</pre>

<p>リクエストハンドラでレスポンスを作成する時に、レスポンスヘッダの content-type に 
text/xml を設定しなければなりません。
xml バージョンと<a href='http://www.opentag.com/xfaq_enc.htm'>文字エンコーディング</a>も指定する必要があります。
エンコーディングの値は非常に重要で、環境に依存します。
二つの一般的な値は "UTF-8" と "iso-8859-1" です。
Java Server Pages (JSP) で、最初の 2、3 行がどのように見えるかは、ここにあります。
<pre>
&lt;% response.setHeader(“Content-Type”, “text/xml”); %&gt;
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
</pre>

そして、これは PHP ではそれらがどのように見えるかです。
<pre>
header("Content-type: text/xml");
echo "&lt;?xml version='1.0' encoding='UTF-8'?"."&gt;\n";
</pre>

<p>Ajax レスポンスについての、いくつかの重要なアイテムに注意して下さい。

<p>最初に、レスポンスは &lt;ajax-response&gt;&lt;/ajax-response&gt; タグで囲まれます。
すべての Rico Ajax レスポンスは、返す XML の root に、この要素を持たなければなりません。
第二に、レスポンスは ajax-response の範囲内に含まれる事に注意して下さい。
レスポンスタグ（&lt;response&gt;&lt;/response&gt;）はレスポンスの内容を囲みます。
&lt;response&gt; タグの type と id 属性は、Rico 1.1 では必要とされていましたが、Rico 2.0 では無視されます。
最後に、&lt;rowcount&gt; 要素に注意して下さい。
これはデータセットの総行数を指定します。
AjaxXML レスポンスにおいて、これは &lt;tr&gt; 要素の数と一致するはずです。

<p>デバッグタグ（&lt;debug&gt;&lt;/debug&gt;）は任意です。
レスポンスはそれらを 0、1、またはそれ以上含むかもしれません。
それぞれのデバッグタグの内容は、Rico の<a href='LiveGrid.html#debug'>メッセージログ機能</a>へ送られます。
Rico プラグインは、ricoXMLquery.php/asp/aspx で ricoXmlResponse.sendDebugMsgs を true に設定することにより、
実行された実際の SQL クエリを返す事が出来ます。
これは、開発の間はとても役に立ちますが、セキュリティーリスク（ユーザに実際のテーブルと列の名前を見せる）
となるので、製品においては削除しなければなりません。

<p>リクエストの進行中にサーバでエラーが発生するなら、サーバはエラーメッセージを &lt;error&gt;&lt;/error&gt; 
タグで囲んでユーザにエラー情報を返す事が出来ます。
例えば。

<pre class='response'>
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;ajax-response&gt;
  &lt;response type='object' id='ex3_updater'&gt;
    &lt;rows update_ui='true' offset='0'&gt;
    &lt;/rows&gt;
    &lt;rowcount&gt;0&lt;/rowcount&gt;
    &lt;error&gt;Unable to retrieve the data&lt;/error&gt;
  &lt;/response&gt;
&lt;/ajax-response&gt;
</pre>

<p>&lt;error&gt; タグが存在すると、いかなる行データや rowcount も無視されます。
このように、エラーを返す時には &lt;rows&gt; と &lt;rowcount&gt; は含まれる事や省略される事が出来ます。
エラーが発生する時、Rico プラグインはデータベース生成エラーを送ります。

<h2><a name='AjaxSQL'>Rico.Buffer.AjaxSQL</a></h2>

<p>AjaxSQL バッファは、AjaxXML バッファにより提供される能力を拡張します。
コンセプトの多くは同じですが、AjaxSQL バッファはより複雑です。
クエリ結果は、一回のレスポンスですべての行を返すのでは無く、塊でバッファに返されます。
また、AjaxSQL バッファはサーバ上でフィルタとソートが発生すると考えられます。
そして、フィルタとソートのパラメータはそれぞれのリクエストに送られなくてはならず、
サーバはそれらのパラメータを正しく処理しなければなりません。
幸いにも、Rico プラグインは、あなたのためにこの複雑さを解決します。

<p>AjaxSQL バッファは以下の javascript を利用して作成されます。

<pre>
buffer=new Rico.Buffer.AjaxSQL(url,options,ajaxOptions)
</pre>

ここに ex2simple.php から取った実例があります。
<pre>
buffer=new Rico.Buffer.AjaxSQL(
  'ricoXMLquery.php', 
  {TimeOut:&lt;? print array_shift(session_get_cookie_params())/60 ?&gt;});
orderGrid=new Rico.LiveGrid ('ex2', buffer, opts);
</pre>

<dl>
<dt>url
<dd>データプロバイダへの url を含んでいる文字列。
<dt><a name='AjaxSQLoptions'>options</a>
<dd>以下のどれかを含む Rico バッファオプションオブジェクト。

<dl>
<dt>bufferTimeout
<dd>タイムアウトを示す前に待ちメッセージをユーザに表示すべきミリ秒の数を指定する整数。
デフォルトは 20000 （20 秒）。

<dt>requestParameters
<dd>XMLHttpRequest の検索文字列に加えられる "parm=value" の形の文字列の配列。

<dt>isEncoded
<dd>レスポンスが HTML エンコードされるかどうかを指定します。デフォルトは true です。
Rico と共に提供されるすべてのプラグインは、レスポンスをエンコードします。

<dt>waitMsg
<dd>XMLHttpRequest レスポンスを待つ間ユーザに表示されるメッセージ。
デフォルトは RicoTranslate.getPhraseById("waitForData")。
これがイメージタグである事が出来る点に注意して下さい、例えば。
<pre>
buffer=new Rico.Buffer.AjaxXML(
  url,
  {waitMsg: "&lt;img src='MySpinner.gif'&gt;"},
  ajaxOptions);
</pre>

<dt>canFilter
<dd>バッファがフィルタリングをサポートするかどうかを示す真偽値。デフォルトは true です。

<dt>largeBufferSize
<dd>バッファのサイズを設定するために利用されます。デフォルトは 7 です。
実際のバッファサイズは「（グリッドの表示行数）* largeBufferSize」に設定されますが、少なくとも 50 です。
そして、4 行を表示するグリッドは 50 のサイズの最小のバッファを手にいれますが、
一方 30 行を表示するグリッドは 210 のサイズを持ちます。

<dt>nearLimitFactor
<dd>ユーザがバッファの最後付近にスクロールした時、データの新しいリクエストのトリガーを決定するのに利用されます。
デフォルトは 1 です。
nearLimit の値は「（グリッドの表示行数）* nearLimitFactor」に設定されます。

<dt>TimeOut
<dd>Rico プラグインは SQL クエリを
<a href='http://www.talkphp.com/general/1077-understanding-life-session.html'>セッション変数</a>に保管します。
サーバはセッションが有効な間だけはデータのリクエストに返答する事が出来ます。
TimeOut オプションはセッションが存続する時間を測るために利用されます。
option.TimeOut が指定され、document に id が "MyGridId_timer" の html 要素があるなら、
その要素の innerHTML はセッションが存続する時間で実装されます。
TimeOut の値は分で指定され、デフォルトを持ちません。

<dt><a name='sortParmFmt'>sortParmFmt</a>
<dd>セットされるならば、sortParmFmt は Rico 列オブジェクトの属性の名前でなければなりません。
Rico 1.1 互換のフォーマットでリクエストを生成するために、"displayName" を設定して下さい。
<pre class='request'>
ricoXMLquery.php?id=ex2&amp;...&amp;sort_col=Column0&amp;sort_dir=ASC
</pre>
リクエストをこのフォーマットで生成するために、"index" を設定して下さい。
<pre class='request'>
ricoXMLquery.php?id=ex2&amp;...&amp;sort_col=0&amp;sort_dir=ASC
</pre>
指定しない（デフォルト）時、ソートパラメータは、このフォーマットで送信されます（'s' に続く列番号）。
これは、Rico プラグインが期待するものです。
<pre class='request'>
ricoXMLquery.php?id=ex2&amp;...&amp;s0=ASC
</pre>
</dl>

<dt>ajaxOptions
<dd>Prototype の Ajax.Request メソッドへ渡される <a href='http://prototypejs.org/api/ajax/options'>Ajax オプションオブジェクト</a>。
"parameters" と "onComplete" オプションは Rico によって利用され、指定されたとしても効果がありません。
"method" オプションのデフォルトは "get" ですが、オーバーライドされる事が出来ます。
</dl>



<h3><a name='AjaxSQLrequests'>AjaxSQL リクエスト</a></h3>

<p>AjaxSQL バッファがより多くのデータを必要とするたびに XMLHttpRequest は生成されます。
offset と page_size パラメータによって指定されるように、データは塊でリクエストされます。
これは、LiveGrid が効率的に何十万ものレコードを表示する事を可能にします。
なぜなら、どんな時でもクライアントサイドバッファに、それらのレコードの小さな部分だけが記録されているからです。
この URL は以下のクエリーストリング（検索）パラメータを含みます。

<dl>
<dt>id
<dd>以前の実例 "ex2" の Rico.LiveGrid() の呼び出しで、最初のパラメータとして指定されたグリッドの id。

<dt>offset
<dd>返さなければならないデータセットの最初のレコード。 AjaxXML では常に "0" です。

<dt>page_size
<dd>データセットで返されなければならないレコードの数。
AjaxXML では常に "-1" で、すべてのレコードが返されなければならない事を意味します。

<dt>get_total
<dd>true なら、そのレスポンスは、指定されたフィルタと共に（リクエストされた塊だけで無く）
データセットの総行数を含む &lt;rowcount&gt; 要素を含むはずです。
"get_total=true" は、どんな時にユーザがフィルタを変更しても、
グリッドを実装するための最初のリクエストの間に送られます。

<pre class='request'>
ricoXMLquery.php?id=ex2&amp;...&amp;get_total=true
</pre>

<dt>sX <span>（ X は列の数です）</span>
<dd>列 X によってソートされるべき結果を指定します。
パラメータは ASC または DESC です。
<a href='#sortParmFmt'>options.sortParmFmt</a> も見て下さい。
たとえ、このパラメータのフォーマットが一度に複数列をソートする事を理論的に許すとしても、
それは現在の LiveGrid UI では不可能です。
<pre class='request'>
ricoXMLquery.php?id=ex2&amp;...&amp;s0=ASC
</pre>

<dt>f[X][op] <span>（ X は列の数です）</span>
<dd>列 X に適応されているフィルタオペレータを指定します。
パラメータは以下の内の一つです。EQ（等しい）、NE（等しく無い）、GE（以上）、LE（以下）、LIKE、NULL、NOTNULL
<pre class='request'>
ricoXMLquery.php?id=ex2&amp;...&amp;f[0][op]=EQ
</pre>

<dt>f[X][len] <span>（ X は列の数です）</span>
<dd>供給されているフィルタの値の数を指定します。
これは EQ、GE、LE、そして LIKE フィルタオペレータでは 1 です。
これは NULL そして NOTNULL オペレータでは 0 です。
これは NE では 1 またはそれ以上です。
<pre class='request'>
ricoXMLquery.php?id=ex2&amp;...&amp;f[0][op]=EQ&amp;f[0][len]=1
</pre>

<dt>f[X][Y] <span>（ X は列の数です）</span>
<dd>EQ、NE、GE、LE、そして LIKE フィルタオペレータのフィルタの（複数の）値を指定します。
Y は 0 から f[X][len]-1 の範囲です。
LIKE オペレータでの '*' は ワイルドカードとして扱われ、
それは Rico プラグインによって多くのデータベースのために '%' に変換されます。
<pre class='request'>
ricoXMLquery.php?id=ex2&amp;...&amp;f[0][op]=EQ&amp;f[0][len]=1&amp;f[0][0]=Column0Value
</pre>
</dl>

<p>加えて、options.requestParameters が指定されるならば、それらもまた含まれる事になります。
そして、ex2 のためのデータのフェッチに利用される完全な URL は、次の通りでしょう。
<pre class='request'>
ricoXMLquery.php?id=ex2&amp;offset=0&amp;page_size=28
</pre>


<h3>AjaxSQL レスポンス</h3>

<p>AjaxSQL レスポンスのフォーマットは、<a href='#AjaxXMLresponse'>AjaxXML レスポンス</a>と全く同じです。

<h2><a name='AjaxJSON'>Rico.Buffer.AjaxJSON</a></h2>

<p>AjaxJSON バッファは Jeremy Green により作成された AjaxSQL バッファの拡張です。
AjaxJSON バッファは、以下の javascript を利用して作成されます。

<pre>
buffer=new Rico.Buffer.AjaxJSON(jsonUrl,options)
</pre>

<dl>
<dt>url
<dd>JSON データプロバイダへの url を含んでいる文字列。

<dt>options
<dd>Rico バッファオプションオブジェクト。
AjaxJSON で利用出来る値は <a href='#AjaxSQLoptions'>AjaxSQL</a> のそれらと同じです。
</dl>


<h3>AjaxJSON リクエスト</h3>

<p>AjaxJSON リクエストのフォーマットは、<a href='#AjaxSQLrequests'>AjaxSQL リクエスト</a>と全く同じです。


<h3>AjaxJSON レスポンス</h3>

<p>ここに JSON フォーマットによる LiveGrid レスポンスの実例があります。

<pre class='response'>
{
  "update_ui":"true",
  "offset":"0",
  "rowCount":"20",
  "rows":[
            {"id":"1","name":"Bob"},
            {"id":"2","name":"Bill"}
         ]
}
</pre>

<p>そのフォーマットは Rico.Buffer.AjaxSQL バッファによって消費される XML に基づくデータに密接に従い、
そしてそれによってすべての値は返されるべきです。
データオブジェクトの 'rows' の値オブジェクトは、行を表す JS ハッシュであるそれぞれの要素による通常の JS 配列です。
ハッシュの key/value の組み合わせは colName/colValue であるべきです。


</body>
</html>
